﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Common.Extension
{
    /// <summary>
    /// 对Switch语法的封装
    /// </summary>
    public static class SwitchExtension
    {
        #region Switch扩展

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="args">参数：对比数值、返回值的方式</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch<string>(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static T Switch<T>(this object obj, params object[] args)
        {
            T defaultVaalue = default(T);
            int length = args.Length;
            if (args.Length % 2 == 1)
            {
                defaultVaalue = args[args.Length - 1].ConvertTo<T>();
                length = length - 1;
            }
            for (int i = 0; i < length; i++)
            {
                object item = args[i];
                i += 1;
                if (length == i)
                {
                    break;
                }
                T value = args[i].ConvertTo<T>();
                if (object.Equals(obj, item))
                {
                    return value;
                }
            }
            return defaultVaalue;
        }

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">当前对象数据类型</typeparam>
        /// <typeparam name="V">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="compare">对比数值</param>
        /// <param name="value">如与对比数值相等则返回此数值</param>
        /// <param name="defaultValue">如都无法匹配时则默认为此参数</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static V Switch<T, V>(this T obj, T compare, V value, V defaultValue = default(V))
        {
            if (object.Equals(obj, compare))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">当前对象数据类型</typeparam>
        /// <typeparam name="V">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="compare1">对比数值1</param>
        /// <param name="value1">如与对比数值1相等则返回此数值</param>
        /// <param name="compare2">对比数值2</param>
        /// <param name="value2">如与对比数值2相等则返回此数值</param>
        /// <param name="defaultValue">如都无法匹配时则默认为此参数</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static V Switch<T, V>(this T obj, T compare1, V value1, T compare2, V value2, V defaultValue = default(V))
        {
            if (object.Equals(obj, compare1))
            {
                return value1;
            }
            if (object.Equals(obj, compare2))
            {
                return value2;
            }
            return defaultValue;
        }

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">当前对象数据类型</typeparam>
        /// <typeparam name="V">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="compare1">对比数值1</param>
        /// <param name="value1">如与对比数值1相等则返回此数值</param>
        /// <param name="compare2">对比数值2</param>
        /// <param name="value2">如与对比数值2相等则返回此数值</param>
        /// <param name="compare3">对比数值3</param>
        /// <param name="value3">如与对比数值3相等则返回此数值</param>
        /// <param name="defaultValue">如都无法匹配时则默认为此参数</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static V Switch<T, V>(this T obj, T compare1, V value1, T compare2, V value2, T compare3, V value3, V defaultValue = default(V))
        {
            if (object.Equals(obj, compare1))
            {
                return value1;
            }
            if (object.Equals(obj, compare2))
            {
                return value2;
            }
            if (object.Equals(obj, compare3))
            {
                return value3;
            }
            return defaultValue;
        }

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">当前对象数据类型</typeparam>
        /// <typeparam name="V">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="compare1">对比数值1</param>
        /// <param name="value1">如与对比数值1相等则返回此数值</param>
        /// <param name="compare2">对比数值2</param>
        /// <param name="value2">如与对比数值2相等则返回此数值</param>
        /// <param name="compare3">对比数值3</param>
        /// <param name="value3">如与对比数值3相等则返回此数值</param>
        /// <param name="compare4">对比数值4</param>
        /// <param name="value4">如与对比数值4相等则返回此数值</param>
        /// <param name="defaultValue">如都无法匹配时则默认为此参数</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static V Switch<T, V>(this T obj, T compare1, V value1, T compare2, V value2, T compare3, V value3, T compare4, V value4, V defaultValue = default(V))
        {
            if (object.Equals(obj, compare1))
            {
                return value1;
            }
            if (object.Equals(obj, compare2))
            {
                return value2;
            }
            if (object.Equals(obj, compare3))
            {
                return value3;
            }
            if (object.Equals(obj, compare4))
            {
                return value4;
            }
            return defaultValue;
        }

        /// <summary>
        /// Switch Case的简化用法
        /// </summary>
        /// <typeparam name="T">当前对象数据类型</typeparam>
        /// <typeparam name="V">返回的数据类型</typeparam>
        /// <param name="obj">当前对象</param>
        /// <param name="compare1">对比数值1</param>
        /// <param name="value1">如与对比数值1相等则返回此数值</param>
        /// <param name="compare2">对比数值2</param>
        /// <param name="value2">如与对比数值2相等则返回此数值</param>
        /// <param name="compare3">对比数值3</param>
        /// <param name="value3">如与对比数值3相等则返回此数值</param>
        /// <param name="compare4">对比数值4</param>
        /// <param name="value4">如与对比数值4相等则返回此数值</param>
        /// <param name="compare5">对比数值5</param>
        /// <param name="value5">如与对比数值5相等则返回此数值</param>
        /// <param name="defaultValue">如都无法匹配时则默认为此参数</param>
        /// <example>
        /// <code><![CDATA[
        /// //常规写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = string.Empty;
        ///     switch (index)
        ///     {
        ///         case 1:
        ///             {
        ///                 text = "我是1";
        ///                 break;
        ///             }
        ///         case 2:
        ///             {
        ///                 text = "我是2";
        ///                 break;
        ///             }
        ///         default:
        ///             text = "我是默认";
        ///             break;
        ///     }
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //用此写法：
        /// for (int index = 1; index < 4; index++)
        /// {
        ///     string text = index.Switch(1, "我是1", 2, "我是2", "我是默认");
        ///     Console.WriteLine("index=" + index + "    返回值：" + text);
        /// }
        /// 
        /// //输出结果：
        /// index = 1  返回值：我是1
        /// index = 2  返回值：我是2
        /// index = 3  返回值：我是默认
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static V Switch<T, V>(this T obj, T compare1, V value1, T compare2, V value2, T compare3, V value3, T compare4, V value4, T compare5, V value5, V defaultValue = default(V))
        {
            if (object.Equals(obj, compare1))
            {
                return value1;
            }
            if (object.Equals(obj, compare2))
            {
                return value2;
            }
            if (object.Equals(obj, compare3))
            {
                return value3;
            }
            if (object.Equals(obj, compare4))
            {
                return value4;
            }
            if (object.Equals(obj, compare5))
            {
                return value5;
            }
            return defaultValue;
        }
        #endregion
    }
}
